﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using MyLib2018;
using System.Security.Cryptography;


namespace CHSN
{
    public class CHSNer
    {
        /// <summary>
        /// 字符转数组
        /// </summary>
        /// <param name="strID"></param>
        /// <param name="type">硬件设备类型,1为硬盘，2为主板，3为BIOS</param>
        /// <returns>返回值带了类型值</returns>
        public byte[] StringToHexByte(string strID,int type)
        {
            string str = type.ToString() + strID;
            return MyConvert.StringToByteArray(str);
        }

        /// <summary>
        /// 获取特征码
        /// </summary>
        /// <returns></returns>
        public string GetFeatureCode()
        {
            byte[] bFeatureCode = GetPhysicalSerialNumber();
            string code = "";
            UInt16 add = 0;
            if(bFeatureCode.Length >= 6)
            {
                for (int i = 0; i < 6; i++) add += (UInt16)((bFeatureCode[i] >> 1) + (0x80 >> i));
                byte[] bCode = new byte[8];
                bCode[0] = bFeatureCode[0];
                bCode[1] = (byte)(add >> 8);
                Array.Copy(bFeatureCode, 1, bCode, 2, 5);//复制6个数据
                bCode[7] = (byte)add;
                foreach (byte b in bCode) code += b.ToString("X2");
            }
            else
            {
                int len = 6 - bFeatureCode.Length;
                byte[] featureCode = new byte[6];
                Array.Copy(bFeatureCode, featureCode, bFeatureCode.Length);
                for (int i = bFeatureCode.Length; i < 6; i++) featureCode[i] = (byte)(0x05 << i);
                for (int i = 0; i < 6; i++) add += (UInt16)((featureCode[i] >> 1) + (0x80 >> i));
                byte[] bCode = new byte[8];
                bCode[0] = featureCode[0];
                bCode[1] = (byte)(add >> 8);
                Array.Copy(featureCode, 1, bCode, 2, 5);//复制6个数据
                bCode[7] = (byte)add;
                foreach (byte b in bCode) code += b.ToString("X2");
            }
            
            return code;
        }

        /// <summary>
        /// 获取物理编号
        /// </summary>
        /// <returns></returns>
        protected byte[] GetPhysicalSerialNumber()
        {
            string strTest = "0102030405060708";
            ManagementClass mc = null;
            ManagementObjectCollection moc = null;

            //硬盘
            mc = new ManagementClass("Win32_PhysicalMedia");
            //网上有提到，用Win32_DiskDrive，但是用Win32_DiskDrive获得的硬盘信息中并不包含SerialNumber属性。   
            moc = mc.GetInstances();
            string strID = null;
            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties["SerialNumber"].Value.ToString();
                strID = strID.Trim();
                break;
            }
            //如果可以读出，即转换
            if(strID != null) return StringToHexByte(strID,1);

            //主板编号
            mc = new ManagementClass("Win32_BaseBoard");
            moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties["SerialNumber"].Value.ToString();
                strID = strID.Trim();
                break;
            }
            //如果可以读出，即转换
            if (strID != null) return StringToHexByte(strID, 2);

            //BIOS编号
            mc = new ManagementClass("Win32_BIOS");
            moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                strID = mo.Properties["SerialNumber"].Value.ToString();
                break;
            }
            //如果可以读出，即转换
            if (strID != null) return StringToHexByte(strID, 3);

            return StringToHexByte(strTest, 0);
        }

        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string UserMd5(string str)
        {
            string encodeStr = str;
            string pwd = "";
            MD5 md5 = MD5.Create();
            // 加密后是一个字节类型的数组
            byte[] s=md5.ComputeHash(Encoding.Unicode.GetBytes(encodeStr));
            // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得    
            for (int i = 0 ; i < s.Length; i++)    {        
                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符        
                pwd = pwd + s[i].ToString("X");
            }
            return pwd;
        }  
        
        public bool RegistrationSoft(string featureCode,string regCode)
        {
            if (UserMd5(featureCode) == regCode)
            {
                //注册成功，需要将注册码写入注册列表，或写入文件中
                
                return true;
            }
            else
                return false;
        }

    }
}
